

<!DOCTYPE html>
<html lang="en">

<head>
  
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Aliwork helper form.js</title>

  <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js"></script>
  <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
  <script src="./build/entry.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
  <!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
  <![endif]-->
  <link href="https://fonts.googleapis.com/css?family=Roboto:100,400,700|Inconsolata,700" rel="stylesheet">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
  <link type="text/css" rel="stylesheet" href="https://jmblog.github.io/color-themes-for-google-code-prettify/themes/tomorrow-night.min.css">
  <link type="text/css" rel="stylesheet" href="styles/app.min.css">
  <link type="text/css" rel="stylesheet" href="styles/iframe.css">
  <link type="text/css" rel="stylesheet" href="styles/custom.css">
  <script async defer src="https://buttons.github.io/buttons.js"></script>

  
</head>



<body class="layout small-header">
    <div id="stickyNavbarOverlay"></div>
    

<div class="top-nav">
    <div class="inner">
        <a id="hamburger" role="button" class="navbar-burger" aria-label="menu" aria-expanded="false">
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
            <span aria-hidden="true"></span>
        </a>
        <div class="logo">
             
                <a class="image" href="index.html">
                    <img src="assets/logo.png" alt="logo">
                </a>
            
             
                <a href="index.html">
                    <h1 class="navbar-item">Aliwork helper</h1>
                </a>
            
        </div>
        <div class="menu">
            
            <div class="navigation">
                <a
                    href="index.html"
                    class="link"
                >
                    Documentation
                </a>
                
                 
                    
                        <a
                            class="link user-link "
                            href="https://docs.aliwork.com/docs/developer/api/about"
                        >
                            宜搭开放API
                        </a>
                    
                
                
            </div>
        </div>
    </div>
</div>
    <div id="main">
        <div
            class="sidebar "
            id="sidebarNav"
        >
            
                <div class="search-wrapper">
                    <input id="search" type="text" placeholder="Search docs..." class="input">
                </div>
            
            <nav>
                
                    <h2><a href="index.html">Documentation</a></h2><div class="category"><h3>Modules</h3><ul><li><a href="module-Form.html">Form</a></li><li><a href="module-UI.html">UI</a></li><li><a href="module-Utils.html">Utils</a></li></ul></div>
                
            </nav>
        </div>
        <div class="core" id="main-content-wrapper">
            <div class="content">
                <header class="page-title">
                    <p>Source</p>
                    <h1>form.js</h1>
                </header>
                



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/**
 * 表单相关方法
 * @module Form
 */

/**
 * 获取表单实例详情
 * @static
 * @param {object} context this上下文
 * @param {string} type 类型，取值为 form-表单或者porcess-流程
 * @param {string} formInstId 表单实例ID
 */
function getFormData(context, type, instId) {
  if (!context) {
    throw Error("context is required");
  }
  if (!type) {
    type = "form";
  }
  if (!instId) {
    throw Error("formInstId is required");
  }

  let req;
  if (type === "form") {
    req = context.dataSourceMap.getFormData
      .load({ formInstId: instId })
      .then((response) => {
        return response.formData;
      });
  } else if (type === "process") {
    req = context.dataSourceMap.getProcessInstance
      .load({
        processInstanceId: instId,
      })
      .then((response) => {
        return response.data;
      });
  }

  return req || Promise.reject(`[Fn getFormData]unknown type: ${type}`);
}

/**
 * searchFormDatas option 参数类型定义
 * @typedef {Object} SearchFormDatasOption
 * @property {object} dynamicOrder - 排序规则，详情参见 {@link https://docs.aliwork.com/docs/developer/api/openAPI#%E6%A0%B9%E6%8D%AE%E6%9D%A1%E4%BB%B6%E6%90%9C%E7%B4%A2%E8%A1%A8%E5%8D%95%E5%AE%9E%E4%BE%8B%E8%AF%A6%E6%83%85%E5%88%97%E8%A1%A8}
 * @property {string} originatorId - 数据提交人/流程发起人工号
 * @property {string} createFrom - 查询在该时间段创建的数据列表
 * @property {string} createTo - 查询在该时间段创建的数据列表
 * @property {string} modifiedFrom - 查询在该时间段有修改的数据列表
 * @property {string} modifiedTo - 查询在该时间段有修改的数据列表
 * @property {string} taskId - 任务ID，仅查询流程表单有效
 * @property {"RUNNING" | "TERMINATED" | "COMPLETED" | "ERROR"} instanceStatus
 * - 实例状态，仅查询流程表单有效,可选值为：RUNNING, TERMINATED, COMPLETED, ERROR。分别代表：运行中，已终止，已完成，异常。
 * @property {"agree" | "disagree"} approvedResult - 流程审批结果，仅查询流程表单有效
 */

/**
 * 查询表单实例ID列表
 * @static
 * @param {object} context this上下文
 * @param {"form" | "process"} type - 表单类型，可选 form、process，分别代表普通表单和流程
 * @param {string} formUuid 表单ID
 * @param {object} searchFieldObject 表单组件查询条件对象
 * @param {number} currentPage 当前页， 默认为1
 * @param {number} pageSize 每页记录数， 默认为10
 * @param {SearchFormDatasOption} options - 查询选项
 * @returns {Promise}
 *
 * @example
 * 使用前请添加数据源：
 * 如果要更新普通表单：
 * 名称：searchFormDataIds
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/searchFormDataIds.json
 * 如果要更新流程表单：
 * 名称：getInstanceIds
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/process/getInstanceIds.json
 */
async function searchFormDataIds(
  context,
  type,
  formUuid,
  searchFieldObject,
  currentPage,
  pageSize,
  options
) {
  if (!context) {
    throw Error("context is required");
  }
  if (!formUuid) {
    throw Error("formUuid is required");
  }
  if (!type) {
    type = "form";
  }

  const searchFieldJson = JSON.stringify(searchFieldObject || {});
  if (options &amp;&amp; options.dynamicOrder) {
    options.dynamicOrder = JSON.stringify(options.dynamicOrder || {});
  }

  let req;
  if (type === "form") {
    req = context.dataSourceMap.searchFormDataIds.load({
      formUuid,
      searchFieldJson,
      currentPage,
      pageSize,
      ...options,
    });
  } else if (type === "process") {
    req = context.dataSourceMap.getInstanceIds.load({
      formUuid,
      searchFieldJson,
      currentPage,
      pageSize,
      ...options,
    });
  } else {
    throw Error("Unknow form type: ", type);
  }

  const response = await req;
  const { currentPage: cPage, totalCount, data: ids } = response;

  return {
    currentPage: cPage,
    totalCount,
    ids,
  };
}

/**
 * 查询符合条件的所有表单实例ID
 * @static
 * @param {object} context this上下文
 * @param {"form" | "process"} type - 表单类型，可选 form、process，分别代表普通表单和流程
 * @param {string} formUuid 表单ID
 * @param {object} searchFieldObject 表单组件查询条件对象
 * @param {SearchFormDatasOption} options - 查询选项
 * @returns {Promise}
 *
 * @example
 * 使用前请添加数据源：
 * 如果要更新普通表单：
 * 名称：searchFormDataIds
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/searchFormDataIds.json
 * 如果要更新流程表单：
 * 名称：getInstanceIds
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/process/getInstanceIds.json
 */
async function searchFormDataIdsAll(
  context,
  type,
  formUuid,
  searchFieldObject,
  options
) {
  if (!type) type = "form";

  let allIds = [];
  let currentPage = 1;
  const pageSize = 100;

  const t = true;
  while (t) {
    const { ids } = await searchFormDataIds(
      context,
      type,
      formUuid,
      searchFieldObject,
      currentPage,
      pageSize,
      options
    );
    allIds = allIds.concat(ids);

    if (ids.length !== pageSize) {
      break;
    }

    currentPage += 1;
  }

  return allIds;
}

/**
 * 查询表单实例数据列表
 * @static
 * @param {object} context this上下文
 * @param {"form" | "process"} type - 表单类型，可选 form、process，分别代表普通表单和流程
 * @param {string} formUuid 表单ID
 * @param {object} searchFieldObject 表单组件查询条件对象
 * @param {number} currentPage 当前页， 默认为1
 * @param {number} pageSize 每页记录数， 默认为10
 * @param {SearchFormDatasOption} options - 查询选项
 * @returns {Promise}
 *
 * @example
 * 使用前请添加数据源：
 * 如果要更新普通表单：
 * 名称：searchFormDatas
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/searchFormDatas.json
 * 如果要更新流程表单：
 * 名称：getInstances
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/process/getInstances.json
 */
async function searchFormDatas(
  context,
  type,
  formUuid,
  searchFieldObject,
  currentPage,
  pageSize,
  options
) {
  if (!context) {
    throw Error("context is required");
  }
  if (!formUuid) {
    throw Error("formUuid is required");
  }
  if (!type) {
    type = "form";
  }

  const searchFieldJson = JSON.stringify(searchFieldObject || {});
  if (options &amp;&amp; options.dynamicOrder) {
    options.dynamicOrder = JSON.stringify(options.dynamicOrder || {});
  }

  let req;
  if (type === "form") {
    req = context.dataSourceMap.searchFormDatas.load({
      formUuid,
      searchFieldJson,
      currentPage,
      pageSize,
      ...options,
    });
  } else if (type === "process") {
    req = context.dataSourceMap.getInstances.load({
      formUuid,
      searchFieldJson,
      currentPage,
      pageSize,
      ...options,
    });
  } else {
    throw Error("Unknow form type: ", type);
  }

  const response = await req;
  const { currentPage: cPage, totalCount, data } = response;
  const formDatas = (data || []).map((item) => ({
    ...item,
    // 普通表单的表单数据在formData属性中
    ...item.formData,
    // 流程表单的表单数据在data属性中
    ...item.data,
  }));

  return {
    currentPage: cPage,
    totalCount,
    formDatas,
  };
}

/**
 * 查询符合条件的所有表单实例
 * @static
 * @param {object} context this上下文
 * @param {"form" | "process"} type - 表单类型，可选 form、process，分别代表普通表单和流程
 * @param {string} formUuid 表单ID
 * @param {object} searchFieldObject 表单组件查询条件对象
 * @param {SearchFormDatasOption} options - 查询选项
 * @returns {Promise}
 */
async function searchFormDatasAll(
  context,
  type,
  formUuid,
  searchFieldObject,
  options
) {
  if (!type) type = "form";

  let allFormDatas = [];
  let currentPage = 1;
  const pageSize = 100;

  const t = true;
  while (t) {
    const { formDatas } = await searchFormDatas(
      context,
      type,
      formUuid,
      searchFieldObject,
      currentPage,
      pageSize,
      options
    );
    allFormDatas = allFormDatas.concat(formDatas);

    if (formDatas.length !== pageSize) {
      break;
    }

    currentPage += 1;
  }

  return allFormDatas;
}

/**
 * 获取子表数据
 * @static
 * @param {object} context this上下文
 * @param {string} formUuid 表单ID
 * @param {string} formInstanceId 表单实例ID
 * @param {string} tableFieldId 子表唯一标识
 * @param {number} currentPage 当前页， 默认为1
 * @param {number} pageSize 每页记录数， 默认为10
 * @returns
 *
 * @example
 * 使用前请添加数据源：
 * 名称：saveFormData
 * 请求方法：GET
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/listTableDataByFormInstIdAndTableId.json
 */
async function fetchSubformDatas(
  context,
  formUuid,
  formInstanceId,
  tableFieldId,
  currentPage,
  pageSize
) {
  if (!context) {
    throw Error("context is required");
  }
  if (!formUuid) {
    throw Error("formUuid is required");
  }
  if (!formInstanceId) {
    throw Error("form instance id is required");
  }
  if (!tableFieldId) {
    throw Error("table field id is required");
  }

  currentPage = currentPage || 1;
  pageSize = pageSize || 10;

  const response = await context.dataSourceMap.fetchSubformDatas.load({
    formUuid,
    formInstanceId,
    tableFieldId,
    currentPage,
    pageSize,
  });

  const { totalCount, data } = response;
  const subformDatas = data || [];

  return {
    totalCount,
    subformDatas,
    currentPage,
  };
}

/**
 * 获取所有子表数据
 * @static
 * @param {object} context this上下文
 * @param {string} formUuid 表单ID
 * @param {string} formInstanceId 表单实例ID
 * @param {string} tableFieldId 子表唯一标识
 */
async function fetchSubformDatasAll(
  context,
  formUuid,
  formInstanceId,
  tableFieldId
) {
  if (!context) {
    throw Error("context is required");
  }
  if (!formUuid) {
    throw Error("formUuid is required");
  }
  if (!formInstanceId) {
    throw Error("form instance id is required");
  }
  if (!tableFieldId) {
    throw Error("table field id is required");
  }

  let allsubformDatas = [];
  let currentPage = 1;
  const pageSize = 50;

  const t = true;
  while (t) {
    const { subformDatas } = await fetchSubformDatas(
      context,
      formUuid,
      formInstanceId,
      tableFieldId,
      currentPage,
      pageSize
    );
    allsubformDatas = allsubformDatas.concat(subformDatas);

    if (subformDatas.length !== pageSize) {
      break;
    }

    currentPage += 1;
  }

  return allsubformDatas;
}

/**
 * 新建表单实例
 * @static
 * @param {object} context this上下文
 * @param {string} formUuid 表单ID
 * @param {object} formData 表单数据对象
 * @returns {string} 表单实例ID
 *
 * @example
 * 使用前请添加数据源：
 * 名称：saveFormData
 * 请求方法：POST
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/saveFormData.json
 */
async function saveFormData(context, formUuid, formData) {
  if (!context) {
    throw Error("context is required");
  }
  if (!formUuid) {
    throw Error("formUuid is required");
  }
  if (!formData) {
    formData = {};
  }

  const formDataJson = JSON.stringify(formData);

  const instanceId = await context.dataSourceMap.saveFormData.load({
    formUuid,
    formDataJson,
  });

  return instanceId;
}

/**
 * 更新表单/流程实例数据
 * @static
 * @param {object} context this上下文
 * @param {"form" | "process"} type - 表单类型，可选 form、process，分别代表普通表单和流程
 * @param {string} instanceId 实例ID
 * @param {object} updateFormData 要更新的表单数据对象
 * @param {boolean} useLatestVersion 是否使用最新的表单版本进行更新，默认为false，仅对普通表单有效
 *
 * @example
 * 使用前请添加数据源：
 * 如果要更新普通表单：
 * 名称：updateFormData
 * 请求方法：POST
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/updateFormData.json
 * 如果要更新流程表单：
 * 名称：updateInstance
 * 请求方法：POST
 * 请求地址：/dingtalk/web/APP_xxxxxx/v1/process/updateInstance.json
 */
async function updateFormData(
  context,
  type,
  instanceId,
  updateFormData,
  useLatestVersion = false
) {
  if (!context) throw Error("context is required");
  if (!instanceId) throw Error("instanceId is required");
  if (!type) type = "form";
  if (!updateFormData) updateFormData = {};

  const updateFormDataJson = JSON.stringify(updateFormData);

  let req;
  if (type === "form") {
    req = context.dataSourceMap.updateFormData.load({
      formInstId: instanceId,
      updateFormDataJson,
      useLatestVersion,
    });
  } else {
    req = context.dataSourceMap.updateInstance.load({
      processInstanceId: instanceId,
      updateFormDataJson,
    });
  }

  await req;
}

/**
 * 删除表单实例数据
 * @static
 * @param {object} context this上下文
 * @param {string} instanceId 实例ID
 *
 * @example
 * // 使用前请添加数据源：
 * // 名称：deleteFormData
 * // 请求方法：POST
 * // 请求地址：/dingtalk/web/APP_xxxxxx/v1/form/deleteFormData.json
 *
 * deleteFormData(this, "FINST-12839128319823").then(() => {
 *   console.log("删除成功");
 * });
 */
async function deleteFormData(context, instanceId) {
  if (!context) throw Error("context is required");
  if (!instanceId) throw Error("instanceId is required");

  const resp = await context.dataSourceMap.deleteFormData.load({
    formInstId: instanceId,
  });

  return resp;
}

/**
 * 激活Tab组件中所有Tab项
 * @static
 * @param {object} context this上下文
 * @param {string} tabFieldId TAB组件唯一标识符
 */
function activateTabItems(context, tabFieldId) {
  const tab = context.$(tabFieldId);
  const tabItemKeys = tab.indexesCache || [];
  tabItemKeys.reverse().forEach((key) => {
    tab.onTabChange(key);
  });
}

export {
  getFormData,
  searchFormDataIds,
  searchFormDataIdsAll,
  searchFormDatas,
  searchFormDatasAll,
  fetchSubformDatas,
  fetchSubformDatasAll,
  saveFormData,
  updateFormData,
  deleteFormData,
  activateTabItems,
};
</code></pre>
        </article>
    </section>




            </div>
            
            <footer class="footer">
                <div class="content has-text-centered">
                    <p>Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.2</a></p>
                    <p class="sidebar-created-by">
                        <a href="https://github.com/SoftwareBrothers/better-docs" target="_blank">BetterDocs theme</a> provided with <i class="fas fa-heart"></i> by
                        <a href="http://softwarebrothers.co" target="_blank">SoftwareBrothers - JavaScript Development Agency</a>
                    </p>
                </div>
            </footer>
            
        </div>
        <div id="side-nav" class="side-nav">
        </div>
    </div>
<script src="scripts/app.min.js"></script>
<script>PR.prettyPrint();</script>
<script src="scripts/linenumber.js"> </script>

<script src="scripts/search.js"> </script>


</body>
</html>
